home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
shells
/
bashsrc.zoo
/
shell.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-05
|
26KB
|
1,033 lines
/* shell.c -- GNU's idea of the POSIX shell specification.
Hopefully, this shell will contain significant enhancements.
This file is part of Bash, the Bourne Again SHell.
Bash is free software; no one can prevent you from reading the source
code, or giving it to someone else.
This file is copyrighted under the GNU General Public License, which
can be found in the file called COPYING.
Copyright (C) 1989 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts
responsibility to anyone for the consequences of using it or for
whether it serves any particular purpose or works at all, unless he
says so in writing. Refer to the GNU Emacs General Public License
for full details.
Everyone is granted permission to copy, modify and redistribute
Bash, but only under the conditions described in the GNU General Public
License. A copy of this license is supposed to have been given to you
along with GNU Emacs so you can know your rights and responsibilities.
It should be in a file named COPYING.
Among other things, the copyright notice and this notice must be
preserved on all copies.
Modification history:
Sunday, January 10th, 1988.
Initial author: Brian Fox
*/
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#ifndef SONY
#include <fcntl.h>
#endif
#include <sys/file.h>
#include <sys/stat.h>
#include <pwd.h>
#if defined (HAVE_VPRINTF)
#include <varargs.h>
#endif
#include "shell.h"
#include "flags.h"
#ifdef SYSV
struct passwd *getpwuid();
#endif
extern char *dist_version;
extern int build_version;
extern int yydebug;
/* Non-zero means that this shell has already been run; i.e. you should
call shell_reinitialize () if you need to start afresh. */
int shell_initialized = 0;
/* The current maintainer of the shell. You change this in the
Makefile. */
#ifndef MAINTAINER
#define MAINTAINER "deliberately-anonymous"
#endif
char *the_current_maintainer = MAINTAINER;
#ifndef PPROMPT
#define PPROMPT "bash\\$ "
#endif
char *primary_prompt = PPROMPT;
#ifndef SPROMPT
#define SPROMPT "bash> "
#endif
char *secondary_prompt = SPROMPT;
COMMAND *global_command = (COMMAND *)NULL;
/* Non-zero after SIGINT. */
int interrupt_state = 0;
/* The current user's name. */
char *current_user_name = (char *)NULL;
/* The current host's name. */
char *current_host_name = (char *)NULL;
/* Non-zero means that this shell is a login shell.
Specifically:
0 = not login shell.
1 = login shell from getty (or equivalent fake out)
-1 = login shell from "-login" flag.
-2 = both from getty, and from flag.
*/
int login_shell = 0;
/* Non-zero means this shell is running interactively. */
int interactive = 0;
/* Non-zero means to remember lines typed to the shell on the history
list. This is different than the user-controlled behaviour; this
becomes zero when we read lines from a file, for example. */
int remember_on_history = 1;
/* Non-zero means this shell is restricted. */
int restricted = 0;
/* Special debugging helper. */
int debugging_login_shell = 0;
/* The environment that the shell passes to other commands. */
char **shell_environment;
/* Non-zero when we are executing a top-level command. */
int executing = 0;
/* The number of commands executed so far. */
int current_command_number = 1;
/* The environment at the top-level REP loop. We use this in the case of
error return. */
jmp_buf top_level, catch;
/* Non-zero is the recursion depth for commands. */
int indirection_level = 0;
/* The number of times BASH has been executed. This is set
by initialize_variables () in variables.c. */
int shell_level = 0;
/* The name of this shell, as taken from argv[0]. */
char *shell_name;
/* The name of the .(shell)rc file. */
char *bashrc_file = "~/.bashrc";
/* Non-zero means to act more like the Bourne shell on startup. */
int act_like_sh = 0;
/* Values for the long-winded argument names. */
int debugging = 0; /* Do debugging things. */
int no_rc = 0; /* Don't execute ~/.bashrc */
int no_profile = 0; /* Don't execute .profile */
int do_version = 0; /* Display interesting version info. */
int quiet = 0; /* Be quiet when starting up. */
int make_login_shell = 0; /* Make this shell be a `-bash' shell. */
int no_line_editing = 0; /* Don't do fancy line editing. */
int no_brace_expansion = 0; /* Non-zero means no foo{a,b} -> fooa fooa. */
/* Some long-winded argument names. These are obviously new. */
#define Int 1
#define Charp 2
struct {
char *name;
int *value;
int type;
} long_args[] = {
{ "debug", &debugging, Int },
{ "norc", &no_rc, Int },
{ "noprofile", &no_profile, Int },
{ "rcfile", (int *)&bashrc_file, Charp},
{ "version", &do_version, Int},
{ "quiet", &quiet, Int},
{ "login", &make_login_shell, Int},
{ "nolineediting", &no_line_editing, Int},
{ "nobraceexpansion", &no_brace_expansion, Int},
{ (char *)NULL, (int *)0x0, 0 }
};
main (argc, argv, env)
int argc;
char **argv, **env;
{
int i, arg_index = 1;
extern int yydebug;
FILE *default_input = stdin;
char *local_pending_command = (char *)NULL;
extern int last_command_exit_value;
int locally_skip_execution = 0, top_level_arg_index;
extern char *base_pathname ();
#ifdef JOB_CONTROL
extern int job_control;
#endif
/* Wait forever if we are debugging a login shell. */
while (debugging_login_shell);
/* If this shell has already been run, then reinitialize it to a
vanilla state. */
if (shell_initialized)
{
shell_reinitialize ();
if (setjmp (top_level))
exit (2);
}
/* Here's a hack. If the name of this shell is "sh", then don't do
any startup files; just try to be more like /bin/sh. */
{
char *tshell_name = base_pathname (argv[0]);
if (*tshell_name == '-')
tshell_name++;
if (strcmp (tshell_name, "sh") == 0)
act_like_sh++;
}
yydebug = 0;
shell_environment = env;
shell_name = argv[0];
if (*shell_name == '-')
{
shell_name++;
login_shell++;
}
#ifdef JOB_CONTROL
if (act_like_sh)
job_control = 0;
#endif
dollar_vars[0] = savestring (argv[0]);
/* Parse argument flags from the input line. */
/* Find full word arguments first. */
while ((arg_index != argc) && *(argv[arg_index]) == '-')
{
for (i = 0; long_args[i].name; i++)
{
if (strcmp (&(argv[arg_index][1]), long_args[i].name) == 0)
{
if (long_args[i].type == Int)
*(long_args[i].value) = 1;
else
{
if (!argv[++arg_index])
{
report_error ("%s: Flag `%s' expected an argument",
shell_name, long_args[i].name);
exit (1);
}
else
*long_args[i].value = (int)argv[arg_index];
}
goto next_arg;
}
}
break; /* No such argument. Maybe flag arg. */
next_arg:
arg_index++;
}
/* If user supplied the "-login" flag, then set and invert LOGIN_SHELL. */
if (make_login_shell)
login_shell = -++login_shell;
/* All done with full word args; do standard shell arg parsing.*/
while (arg_index != argc && argv[arg_index] &&
(*(argv[arg_index]) == '-' || (*argv[arg_index] == '+')))
{
/* There are flag arguments, so parse them. */
int arg_character;
int on_or_off = (*argv[arg_index]);
int i = 1;
while (arg_character = (argv[arg_index])[i++])
{
switch (arg_character)
{
case 'c':
/* The next arg is a command to execute, and the following args
are $1 .. $n respectively. */
local_pending_command = argv[++arg_index];
if (!local_pending_command)
{
report_error ("`%cc' requires an argument", on_or_off);
exit (1);
}
arg_index++;
goto after_flags;
break